package com.zmn.oms.zmn.business.impl.work.autoflow;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.common.constant.MessageQueueTagConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.model.dto.work.autoflow.FlowDistributeDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderAssignDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderWorkGrabDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.state.WorkAutoFlowBService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;


/**
 * 类描述：工单自动流转
 *
 * @author heciqi
 * @date 2019/10/28 20:06
 */
@Slf4j
@Service
public class WorkFlowContextBServiceImpl implements WorkFlowContextBService {
	@Resource(name="flowTagBService")
	WorkAutoFlowBService<OrderWork> flowTagBService;
	@Resource(name="flowConfirmBService")
	WorkAutoFlowBService<OrderWork> flowConfirmBService;
	@Resource(name="flowAssignBService")
	WorkAutoFlowBService<OrderAssignDTO> flowAssignBService;
	@Resource(name="flowGrabBService")
	WorkAutoFlowBService<OrderWorkGrabDTO> flowGrabBService;
	@Resource(name="flowNonGridGrabBServiceImpl")
	WorkAutoFlowBService<OrderWorkGrabDTO> flowNonGridGrabBServiceImpl;
	@Resource(name="flowDistributeBService")
	WorkAutoFlowBService<FlowDistributeDTO> flowDistributeBService;
	@Resource(name="flowReviewBService")
	WorkAutoFlowBService<OrderWork> flowReviewBService;
	@Resource(name="flowCompleteBService")
	WorkAutoFlowBService<OrderWork> flowCompleteBService;
	@Resource(name="flowCheckoutBService")
	WorkAutoFlowBService<OrderWork> flowCheckoutBService;
	@Resource(name="flowAccountBService")
	WorkAutoFlowBService<OrderWork> flowAccountBService;
	@Autowired
	OrderWorkService orderWorkService;
	@Resource
	private ZmnMQSender zmnMQSender;
	@Resource
	private RedisManager redisManager;
	@Override
	public void asyncAutoFlow(Long orderId, Long workId) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("orderId", orderId);
		jsonObject.put("workId", workId);
		String key = String.valueOf(workId);
		String data = jsonObject.toJSONString();
		log.info("自动流转发送队列key[{}]data[{}]", key, data);
		// 未自动流转完不能操作，5秒失效，流转完解锁
		redisManager.setex(String.format(RedisKeyConsts.AUTO_FLOW_LOCK, workId), Boolean.TRUE.toString(), 5);
		zmnMQSender.send(MessageQueueTopicConstant.ZMN_TOPIC_OMS, MessageQueueTagConsts.WORK_AUTO_FLOW, key, data);
	}

	@Override
	public void asyncAutoFlowDelay(Long orderId, Long workId, int seconds) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("orderId", orderId);
		jsonObject.put("workId", workId);
		String key = String.valueOf(workId);
		String data = jsonObject.toJSONString();
		long time = System.currentTimeMillis() + 1000 * seconds;// 延迟5秒发送
		log.info("自动流转延时秒发送队列key[{}]data[{}]", key, data);
		zmnMQSender.sendWithStartDeliverTime(MessageQueueTopicConstant.ZMN_TOPIC_OMS, MessageQueueTagConsts.WORK_AUTO_FLOW, key, data, time);
	}

	@Override
	public void asyncAutoFlowDelayMillis(Long orderId, Long workId, int millis) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("orderId", orderId);
		jsonObject.put("workId", workId);
		String key = String.valueOf(workId);
		String data = jsonObject.toJSONString();
		long time = System.currentTimeMillis() + millis;
		log.info("自动流转延时毫秒发送队列key[{}]data[{}]", key, data);
		zmnMQSender.sendWithStartDeliverTime(MessageQueueTopicConstant.ZMN_TOPIC_OMS, MessageQueueTagConsts.WORK_AUTO_FLOW, key, data, time);
	}

	@Override
	public void autoFlow(Long orderId, Long workId) {
		OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
		this.autoFlow(orderWork);
	}

	@Override
	public void autoFlow(OrderWork orderWork) {

		Boolean baseCondition = Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DISCARD);
		if (baseCondition) {
			return;
		}

		// 标记了禁止弃单的订单，不自动流转。这种类型的订单处于等待渠道支付状态，如果超时仍未支付，会自动弃单。
		boolean waitingChannelPrepay = Objects.equals(orderWork.getDisableDiscard(), GlobalConsts.YES);
		if (waitingChannelPrepay) {
			return;
		}

		log.info("自动流转-start[{}]", orderWork.getWorkId());

		// 自动打标记
		ResultDTO<OrderWork> tagCondition = flowTagBService.condition(orderWork);
		if (tagCondition.isStatusBool()) {
			flowTagBService.execute(tagCondition.getData());
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动打标签-false[{}]", tagCondition.getMessage());
		}

		// 自动确认
		ResultDTO<OrderWork> confirmCondition = flowConfirmBService.condition(orderWork);
		if (confirmCondition.isStatusBool()) {
			flowConfirmBService.execute(confirmCondition.getData());
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动确认-false[{}]", confirmCondition.getMessage());
		}

		// 自动分单
		ResultDTO<OrderAssignDTO> assignCondition = flowAssignBService.condition(orderWork);
		if (assignCondition.isStatusBool()) {
			flowAssignBService.execute(assignCondition.getData());
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动分单-false[{}],[{}]", orderWork.getWorkId(), assignCondition.getMessage());
		}

		// 抢单
		ResultDTO<OrderWorkGrabDTO> grabCondition = flowGrabBService.condition(orderWork);
		log.info("自动抢单方式判断结果-[{}],[{}]", orderWork.getWorkId(), JSON.toJSONString(grabCondition));
		if (grabCondition.isStatusBool()) {
			flowGrabBService.execute(grabCondition.getData());
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getOrderId());
		} else {
			log.info("自动抢单方式-false[{}],[{}]", orderWork.getWorkId(), grabCondition.getMessage());
		}

		// 无网格抢单
		ResultDTO<OrderWorkGrabDTO> noGridGrabCondition = flowNonGridGrabBServiceImpl.condition(orderWork);
		log.debug("无网格自动抢单方式判断结果-[{}],[{}]", orderWork.getWorkId(), JSON.toJSONString(noGridGrabCondition));
		if (noGridGrabCondition.isStatusBool()) {
			flowNonGridGrabBServiceImpl.execute(noGridGrabCondition.getData());
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getOrderId());
		} else {
			log.info("无网格自动抢单方式-false[{}],[{}]", orderWork.getWorkId(), noGridGrabCondition.getMessage());
		}

		// 自动派单
		ResultDTO<FlowDistributeDTO> distributeCondition = flowDistributeBService.condition(orderWork);
		if (distributeCondition.isStatusBool()) {
			FlowDistributeDTO flowDistributeDTO = new FlowDistributeDTO();
			flowDistributeDTO.setOrderWork(orderWork);
			if (assignCondition.isStatusBool()) {
				flowDistributeDTO.setRecommendMasterId(assignCondition.getData() != null ? assignCondition.getData().getRecommendMasterId() : null);
			} else {
				if (NumberUtil.isNotNullOrZero(orderWork.getRecommenderId()) && Objects.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER, orderWork.getRecommenderType())) {
					flowDistributeDTO.setRecommendMasterId(orderWork.getRecommenderId().intValue());
				}
			}
			flowDistributeBService.execute(flowDistributeDTO);
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动派单-false[{}],[{}]", orderWork.getWorkId(), distributeCondition.getMessage());
		}

		// 自动服务审核
		ResultDTO<OrderWork> reviewCondition = flowReviewBService.condition(orderWork);
		if (reviewCondition.isStatusBool()) {
			flowReviewBService.execute(orderWork);
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动服务审核-false[{}],[{}]", orderWork.getWorkId(), reviewCondition.getMessage());
		}

		// 自动完成审核（F端）
		ResultDTO<OrderWork> completeCondition = flowCompleteBService.condition(orderWork);
		if (completeCondition.isStatusBool()) {
			flowCompleteBService.execute(orderWork);
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动完成（F）-false[{}],[{}]", orderWork.getWorkId(), completeCondition.getMessage());
		}

		// 自动收单（F端）
		ResultDTO<OrderWork> checkoutCondition = flowCheckoutBService.condition(orderWork);
		if (checkoutCondition.isStatusBool()) {
			flowCheckoutBService.execute(orderWork);
			orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
		} else {
			log.info("自动收单（F）-false[{}],[{}]", orderWork.getWorkId(), checkoutCondition.getMessage());
		}

		// 自动算账
		ResultDTO<OrderWork> accountCondition = flowAccountBService.condition(orderWork);
		if (accountCondition.isStatusBool()) {
			flowAccountBService.execute(orderWork);
		} else {
			log.info("自动算账 -false[{}],[{}]", orderWork.getWorkId(), accountCondition.getMessage());
		}

		log.info("自动流转-end[{}]", orderWork.getWorkId());
	}
}
